﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Weapon.cs" company="">
//   
// </copyright>
// <summary>
//   An object which the player uses to kill enemies.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

/*
 * Author: Barbara Carboni
 * Created: 17-11-2011 
 */

namespace ITU_vs_Zombies.Stuff
{
    using System;
    using System.Diagnostics.Contracts;

    using ITU_vs_Zombies.Movement;

    using Microsoft.Xna.Framework;

    /// <summary>
    /// An object which the player uses to kill enemies.
    /// </summary>
    [Serializable]
    public abstract class Weapon : ExtraObject
    {
        #region Constants and Fields

        /// <summary>
        /// The charge rate.
        /// Each primary weapon has a different charge rate which limits how often you can fire.
        /// </summary>
        protected TimeSpan ChargeRate;

        /// <summary>
        /// The damage.
        /// </summary>
        private uint damage;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Weapon"/> class.
        /// </summary>
        /// <param name="image">
        /// The Image. 
        /// </param>
        /// <param name="numberFrames">
        /// The number of frames. 
        /// </param>
        /// <param name="numberFloor">
        /// The number of floor. 
        /// </param>
        /// <param name="position">
        /// The position. 
        /// </param>
        /// <param name="damage">
        /// The damage. 
        /// </param>
        /// <param name="chargeRate">
        /// The charge rate. 
        /// </param>
        /// <param name="sound">
        /// The sound. 
        /// </param>
        public Weapon(
            string image, 
            uint numberFrames, 
            int numberFloor, 
            Vector2 position, 
            uint damage, 
            TimeSpan chargeRate, 
            string sound)
            : base(image, numberFrames, numberFloor, position, sound)
        {
            Contract.Requires(image != null);
            Contract.Requires(sound != null);
            Contract.Requires(numberFrames > 0);
            Contract.Requires(damage > 0);
            Contract.Requires(position.X >= 0 && position.Y >= 0);
            this.Damage = damage;
            this.ChargeRate = chargeRate;
            this.LastUse = new TimeSpan(0);
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets Damage.
        /// </summary>
        public uint Damage
        {
            get
            {
                Contract.Ensures(Contract.Result<uint>() > 0);
                return this.damage;
            }

            private set
            {
                Contract.Requires(value > 0);
                Contract.Ensures(this.Damage == value);
                this.damage = value;
            }
        }

        /// <summary>
        /// Gets or sets the last Hit.
        /// </summary>
        public TimeSpan LastUse { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// The clone.
        /// </summary>
        /// <returns>
        /// The clone.
        /// </returns>
        public override object Clone()
        {
            var weapon = (Weapon)base.Clone();
            weapon.Damage = this.Damage;
            weapon.LastUse = this.LastUse;
            return weapon;
        }

        /// <summary>
        /// The use.
        /// </summary>
        /// <param name="gameTime">
        /// The game Time.
        /// </param>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="direction">
        /// The direction.
        /// </param>
        public virtual void Use(GameTime gameTime, Vector2 position, MovementsEnum direction)
        {
            Contract.Requires(gameTime != null);
            Contract.Requires(this.Sound != null);
        }

        #endregion

        #region Methods

        /// <summary>
        /// The can use.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        /// <returns>
        /// The can use.
        /// </returns>
        protected virtual bool CanUse(GameTime gameTime)
        {
            Contract.Requires(gameTime != null);
            return false;
        }

        #endregion
    }
}